<template>
  <div>
    <button @click="startSending" :disabled="isRecording">开始对讲</button>
    <button @click="stopSending" :disabled="!isRecording">停止对讲</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      audioContext: null,
      mediaStream: null,
      processor: null,
      isSending: false,
      frameSize: 160, // 160样本 * 16位 = 320字节
      bufferSize: 256,
      tempBuffer: null,

      input: null,
      isRecording: false,
      stream: null,

      setInterval:null
    };
  },
  methods: {
    async startSending() {
      try {

        // 初始化音频采集
        const stream = await navigator.mediaDevices.getUserMedia({ audio: {
            sampleRate: 8000,
            channelCount: 1
          } });
        this.stream = stream
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
          sampleRate: 8000
        });
        this.input = this.audioContext.createMediaStreamSource(stream);

        // 创建音频处理节点
        this.processor = this.audioContext.createScriptProcessor(4096, 1, 1);

        // 配置处理参数
        this.processor.onaudioprocess = (e) => {
          const pcmData = e.inputBuffer.getChannelData(0);
          const pcm16Bit = this.floatTo16BitPCM(pcmData);

          // 按20ms切割数据：8000Hz采样率下，20ms=160样本 → PCM数据长度=160*2=320字节
          const chunkSize = 160; // 320字节
          for (let i = 0; i < pcm16Bit.length; i += chunkSize) {
            const chunk = pcm16Bit.slice(i, i + chunkSize);
            if (chunk.length === chunkSize && this.$socket.readyState === WebSocket.OPEN) {
              this.$socket.send(chunk.buffer);
              console.log(`发送音频块：${chunk.length * 2}字节`);
            }
          }


          // this.setInterval = setInterval(()=>{
          //
          // },20)

          // this.$socket.send(this.floatTo16BitPCM(pcmData));
        };

        // 连接音频节点
        this.input.connect(this.processor);
        this.processor.connect(this.audioContext.destination);
        this.isRecording = true;


        // // 获取麦克风原始PCM数据（16位、8kHz、单声道）
        // const stream = await navigator.mediaDevices.getUserMedia({
        //   audio: {
        //     sampleRate: 8000,
        //     channelCount: 1,
        //     sampleSize: 16,
        //   },
        // });
        //
        // this.audioContext = new AudioContext({ sampleRate: 8000 });
        // const source = this.audioContext.createMediaStreamSource(stream);
        // this.processor = this.audioContext.createScriptProcessor(this.bufferSize, 1, 1);
        //
        // source.connect(this.processor);
        // this.processor.connect(this.audioContext.destination);
        //
        // this.processor.onaudioprocess = (e) => {
        //   const pcmData = e.inputBuffer.getChannelData(0);
        //
        //   const chunkSize =128;
        //   for (let i = 0;i<pcmData.length;i+=chunkSize){
        //     const chunk = pcmData.slice(i,i+chunkSize)
        //     const int16Data = this.floatTo16BitPCM(chunk); // 转换为16位小端字节序
        //     const g711Data=this.encodeALaw(int16Data);
        //
        //     if (this.tempBuffer){
        //       const mergedData = new Int16Array([...this.tempBuffer, ...int16Data])
        //       const finalG711 = this.encodeALaw(mergedData.slice(0,160))
        //       this.$socket.send(finalG711)
        //       this.tempBuffer = null
        //     }else{
        //       this.tempBuffer = int16Data
        //     }
        //   }
        // };
        //
        // this.isSending = true;
      } catch (err) {
        console.error("麦克风初始化失败:", err);
      }
    },
    encodeALaw(input) {
      const buffer = new Uint8Array(input.length);
      for (let i = 0; i < input.length; i++) {
        let sample = Math.floor(input[i] * 32768); // 归一化到16位整型（-32768~32767）
        sample = Math.max(-32768, Math.min(32767, sample));

        let sign = sample < 0 ? 0x00 : 0x80;
        let absSample = Math.abs(sample);

        // A-law量化表（ITU-T G.711标准）
        let segment;
        if (absSample >= 256) {
          segment = 7;
          for (let j = 6; j >= 0; j--) {
            if (absSample >= (256 << j)) {
              segment = j + 1;
              break;
            }
          }
        } else {
          segment = 0;
        }

        const quantization = (absSample >> (segment + 3)) & 0x0F;
        const code = (segment << 4) | quantization;
        buffer[i] = sign ^ code;
      }
      return buffer;
    },

    floatTo16BitPCM(input) {
      const output = new Int16Array(input.length);
      for (let i = 0; i < input.length; i++) {
        const s = Math.max(-1, Math.min(1, input[i]));
        output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
      }
      return output;
    },

    stopSending() {
      if (this.input) {
        if (this.stream) {
          this.stream.getTracks().forEach(track => track.stop());
        }
        this.input.disconnect();
        this.processor.disconnect();
        this.isRecording = false;
      }


      return
      if (this.processor) {
        this.$message.warning(1111111111111111111111111111)
        this.processor.disconnect();
        this.audioContext.close();
        this.isSending = false;
      }
    },
  },
};

</script>

<style scoped lang="scss">

</style>
